// 轻量封装 MediaPipe Pose（基于 @mediapipe/pose 脚本全局变量）
// 便于在 React 组件中复用与统一管理生命周期

export type PoseOnResults = (results: any) => void;

export interface PoseControllerOptions {
  width: number;
  height: number;
  onResults: PoseOnResults;
  locateFileBaseUrl?: string; // 可覆盖 CDN
}

export class PoseController {
  private pose: any | null = null;
  private camera: any | null = null;
  private videoEl: HTMLVideoElement;
  private width: number;
  private height: number;
  private onResults: PoseOnResults;
  private locateFileBaseUrl: string;

  constructor(videoEl: HTMLVideoElement, options: PoseControllerOptions) {
    this.videoEl = videoEl;
    this.width = options.width;
    this.height = options.height;
    this.onResults = options.onResults;
    this.locateFileBaseUrl =
      options.locateFileBaseUrl ?? "https://cdn.jsdelivr.net/npm/@mediapipe/pose/";
  }

  init(): void {
    const w = window as any;
    if (!w.Pose || !w.Camera) {
      throw new Error("MediaPipe Pose 未加载。请确保在 index.html 中引入 pose.js 与 camera_utils.js");
    }

    this.pose = new w.Pose({
      locateFile: (file: string) => `${this.locateFileBaseUrl}${file}`,
    });

    this.pose.setOptions({
      modelComplexity: 1,
      smoothLandmarks: true,
      minDetectionConfidence: 0.5,
      minTrackingConfidence: 0.5,
    });

    this.pose.onResults((results: any) => {
      this.onResults(results);
    });

    this.camera = new w.Camera(this.videoEl, {
      onFrame: async () => {
        await this.pose!.send({ image: this.videoEl });
      },
      width: this.width,
      height: this.height,
    });
  }

  async start(): Promise<void> {
    if (!this.pose || !this.camera) this.init();
    await this.camera!.start();
  }

  stop(): void {
    if (this.camera) this.camera.stop();
  }

  dispose(): void {
    this.stop();
    if (this.pose) this.pose.close();
    this.pose = null;
    this.camera = null;
  }
}


